home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
101-125
/
118
/
empire
/
src
/
source.zoo
/
parse.d
< prev
next >
Wrap
Text File
|
1987-12-02
|
15KB
|
807 lines
#include:util.g
#empire.g
#empfunc.g
/*
* skipBlanks - skip past blanks in input line.
*/
proc skipBlanks()void:
while InputPtr* = ' ' or InputPtr* = '\t' do
InputPtr := InputPtr + 1;
od;
corp;
/*
* doSkipBlanks - skip blanks, return 'true'
*/
proc doSkipBlanks()bool:
skipBlanks();
true
corp;
/*
* skipWord - skip up to a blank on the input line.
*/
proc skipWord()void:
while InputPtr* ~= ' ' and InputPtr* ~= '\t' and InputPtr* ~= '\e' do
InputPtr := InputPtr + 1;
od;
corp;
/*
* getNumber - read in a number.
*/
proc getNumber(*int pNum)bool:
int n;
bool isNeg;
if InputPtr* = '-' then
isNeg := true;
InputPtr := InputPtr + 1;
elif InputPtr* = '+' then
isNeg := false;
InputPtr := InputPtr + 1;
else
isNeg := false;
fi;
if InputPtr* >= '0' and InputPtr* <= '9' then
n := 0;
while InputPtr* >= '0' and InputPtr* <= '9' do
n := n * 10 + (InputPtr* - '0');
InputPtr := InputPtr + 1;
od;
pNum* := if isNeg then -n else n fi;
true
else
if InputPtr* = '\e' then
err("missing number");
else
err("invalid number");
InputPtr* := '\e';
fi;
false
fi
corp;
/*
* reqNumber - get (and prompt for if needed) a number.
*/
proc reqNumber(*int pN; *char prompt)bool:
bool gotOne;
ushort stat;
if InputPtr* = '\e' then
while
write(PromptOut; prompt);
if readln(Chin; pN*) then
gotOne := true;
false
else
stat := ioerror(Chin);
if stat = CH_MISSING or stat = CH_EOF then
if stat = CH_MISSING then
readln(Chin;);
fi;
gotOne := false;
false
else
readln(Chin;);
true
fi
fi
do
err("invalid number, try again");
od;
gotOne
else
getNumber(pN)
fi
corp;
/*
* getPosRange - get a positive value less than or equal to a given amount
*/
proc getPosRange(*uint pQuan; uint maximum)bool:
int n;
if getNumber(&n) then
if n < 0 or make(n, uint) > maximum then
writeln(PromptOut; "*** value must be 0 - ", maximum, " ***");
false
else
pQuan* := n;
true
fi
else
false
fi
corp;
/*
* reqPosRange - get/request a positive value
*/
proc reqPosRange(*uint pQuan; uint maximum; *char prompt)bool:
bool gotOne;
if InputPtr* = '\e' then
gotOne := true;
while
write(PromptOut; prompt);
if not readLine(&InputBuffer[0], INPUT_LENGTH) or
InputBuffer[0] = '\e' then
gotOne := false;
false
else
InputPtr := &InputBuffer[0];
skipBlanks();
not getPosRange(pQuan, maximum)
fi
do
od;
gotOne
else
getPosRange(pQuan, maximum)
fi
corp;
/*
* getPosRange1 - get a number within a given range, with 1 decimal digit.
*/
proc getPosRange1(*uint pNumber; uint maximum)bool:
uint n;
bool hadDecimal, bad;
hadDecimal := false;
if InputPtr* >= '0' and InputPtr* <= '9' or InputPtr* = '.' then
n := 0;
while InputPtr* >= '0' and InputPtr* <= '9' do
n := n * 10 + (InputPtr* - '0');
InputPtr := InputPtr + 1;
od;
if InputPtr* = '.' then
InputPtr := InputPtr + 1;
if InputPtr* >= '0' and InputPtr* <= '9' then
n := n * 10 + (InputPtr* - '0');
InputPtr := InputPtr + 1;
while InputPtr* >= '0' and InputPtr* <= '9' do
InputPtr := InputPtr + 1;
od;
else
n := n * 10;
fi;
else
n := n * 10;
fi;
if InputPtr* ~= '\e' and InputPtr* ~= ' ' and InputPtr* ~= '\t' then
err("invalid digit");
bad := true;
fi;
else
err("invalid digit");
bad := true;
fi;
if not bad then
if n > maximum then
err("value too large");
bad := true;
else
pNumber* := n;
fi;
fi;
if bad then
InputPtr* := '\e';
fi;
not bad
corp;
/*
* reqPosRange1 - req a number within a given range, with 1 decimal digit.
*/
proc reqPosRange1(*uint pNumber; uint maximum; *char prompt)bool:
bool gotOne;
if InputPtr* = '\e' then
gotOne := true;
while
write(PromptOut; prompt);
if not readLine(&InputBuffer[0], INPUT_LENGTH) or
InputBuffer[0] = '\e' then
gotOne := false;
false
else
InputPtr := &InputBuffer[0];
skipBlanks();
not getPosRange1(pNumber, maximum)
fi
do
od;
gotOne
else
getPosRange1(pNumber, maximum)
fi
corp;
/*
* getPair - get a coordinate pair.
*/
proc getPair(*int pA, pB)bool:
if getNumber(pA) then
if InputPtr* = ':' then
InputPtr := InputPtr + 1;
getNumber(pB)
elif InputPtr* = ',' or InputPtr* = '?' or InputPtr* = ' ' or
InputPtr* = '\t' or InputPtr* = '/' or InputPtr* = '\e' then
pB* := pA*;
true
else
err("missing ':' for coordinate pair");
InputPtr* := '\e';
false
fi
else
false
fi
corp;
/*
* getBox - get a pair of sector designations (a rectangle).
*/
proc getBox(*int pA, pB, pC, pD)bool:
uint i;
if InputPtr* = '\#' then
InputPtr := InputPtr + 1;
if InputPtr* >= '0' and InputPtr* <= '3' or InputPtr* = '\e' or
InputPtr* = ' ' or InputPtr* = '\t' or
InputPtr* = '/' or InputPtr* = '?' then
if InputPtr* >= '0' and InputPtr* <= '0' + (REALM_MAX - 1) then
i := InputPtr* - '0';
InputPtr := InputPtr + 1;
else
i := 0;
fi;
pA* := ThisCountry*.c_realms[i].r_top;
pB* := ThisCountry*.c_realms[i].r_bottom;
pC* := ThisCountry*.c_realms[i].r_left;
pD* := ThisCountry*.c_realms[i].r_right;
fi;
if InputPtr* ~= ' ' and InputPtr* ~= '\e' and InputPtr* ~= '\t' and
InputPtr* ~= '/' and InputPtr* ~= '?' then
err("illegal characters in realm");
InputPtr* := '\e';
false
else
true
fi
elif getPair(pA, pB) then
if InputPtr* = ',' then
InputPtr := InputPtr + 1;
if getPair(pC, pD) then
if pA* > pB* then
err("top > bottom");
false
elif pC* > pD* then
err("right > left");
false
else
true
fi
else
false
fi
else
err("missing ',' for sectors specification");
InputPtr* := '\e';
false
fi
else
false
fi
corp;
/*
* reqBox - get (prompting for if necessary) a rectangle specification.
*/
proc reqBox(*int pA, pB, pC, pD; *char prompt)bool:
bool gotOne;
if InputPtr* = '\e' then
gotOne := true;
while
write(PromptOut; prompt);
if not readLine(&InputBuffer[0], INPUT_LENGTH) or
InputBuffer[0] = '\e' then
gotOne := false;
false
else
InputPtr := &InputBuffer[0];
skipBlanks();
not getBox(pA, pB, pC, pD)
fi
do
od;
gotOne
else
getBox(pA, pB, pC, pD)
fi
corp;
/*
* getSector - get a coordinate pair.
*/
proc getSector(*int pA, pB)bool:
if getNumber(pA) then
if InputPtr* = ',' then
InputPtr := InputPtr + 1;
getNumber(pB)
else
err("missing ',' for sector number");
InputPtr* := '\e';
false
fi
else
false
fi
corp;
/*
* reqSector - get (prompting if needed) a single sector spec.
*/
proc reqSector(*int pA, pB; *char prompt)bool:
bool gotOne;
if InputPtr* = '\e' then
gotOne := true;
while
write(PromptOut; prompt);
if not readLine(&InputBuffer[0], INPUT_LENGTH) or
InputBuffer[0] = '\e' then
gotOne := false;
false
else
InputPtr := &InputBuffer[0];
skipBlanks();
not getSector(pA, pB)
fi
do
od;
gotOne
else
getSector(pA, pB)
fi
corp;
/*
* reqChar - get (prompting if needed) a character in the given set.
*/
proc reqChar(*char pChar, validSet, prompt, errMess)bool:
*char p;
char ch;
if InputPtr* = '\e' then
while
write(PromptOut; prompt);
if readln(Chin; ch) then
p := validSet;
while p* ~= ch and p* ~= '\e' do
p := p + 1;
od;
if p* = '\e' then
err(errMess);
true
else
false
fi
else
pretend(ioerror(Chin), void);
readln(Chin;);
ch := ' ';
false
fi
do
od;
pChar* := ch;
ch ~= ' '
else
ch := InputPtr*;
InputPtr := InputPtr + 1;
while validSet* ~= ch and validSet* ~= '\e' do
validSet := validSet + 1;
od;
if validSet* = '\e' then
err(errMess);
false
else
pChar* := ch;
if InputPtr* ~= '\e' and InputPtr* ~= ' ' and
InputPtr* ~= '\t' then
err("excess characters after type on command line");
false
else
true
fi
fi
fi
corp;
/*
* reqCmsgpob - get (prompting if needed) a cmsgpob type.
*/
proc reqCmsgpob(*ItemType_t pWhich; *char prompt)bool:
char ch;
if reqChar(&ch, &ItemChar[0], prompt, "invalid item type") then
pWhich* := getIndex(&ItemChar[0], ch) + it_first;
true
else
false
fi
corp;
/*
* reqDesig - get (prompting if needed) a sector designation character.
*/
proc reqDesig(*SectorType_t pDesig; *char prompt)bool:
char ch;
if reqChar(&ch, &SectorChar[0], prompt, "invalid sector designation") then
pDesig* := getIndex(&SectorChar[0], ch) + s_first;
true
else
false
fi
corp;
/*
* reqShipType - get a ship type character.
*/
proc reqShipType(*ShipType_t pType; *char prompt)bool:
char ch;
if reqChar(&ch, &ShipChar[0], prompt, "invalid ship type") then
pType* := getIndex(&ShipChar[0], ch) + st_first;
true
else
false
fi
corp;
/*
* reqBridgeDirection - get a bridge span building direction.
*/
proc reqBridgeDirection(*char pDir, prompt)bool:
reqChar(pDir, "udlr", prompt, "invalid span direction")
corp;
/*
* getCountry - get a country name or number from the input line.
*/
proc getCountry(*uint pCountry)bool:
*char name, p;
int n;
uint n1;
if InputPtr* = '\e' then
false
elif InputPtr* >= '0' and InputPtr* <= '9' then
if getNumber(&n) then
n1 := n;
if n >= 0 and n1 < World.w_currCountries then
pCountry* := n1;
true
elif ThisCountryNumber = DEITY and n >= 0 and
n1 < World.w_maxCountries then
pCountry* := n1;
writeln(PromptOut;);
writeln(PromptOut;);
writeln(PromptOut;
"*** Warning - this country is still inactive ***");
writeln(PromptOut;);
writeln(PromptOut;);
true
else
err("country number out of range");
false
fi
else
false
fi
else
name := InputPtr;
skipWord();
p := InputPtr;
skipBlanks();
p* := '\e';
n1 := 0;
while n1 < World.w_currCountries and
not CharsEqual(name, &Country[n1].c_name[0]) do
n1 := n1 + 1;
od;
if n1 = World.w_currCountries then
err("no country by that name");
false
else
pCountry* := n1;
true
fi
fi
corp;
/*
* reqCountry - get (promting if needed) a country name or number.
*/
proc reqCountry(*uint pCountry; *char prompt)bool:
bool gotOne;
if InputPtr* = '\e' then
gotOne := true;
while
write(PromptOut; prompt);
if not readLine(&InputBuffer[0], INPUT_LENGTH) or
InputBuffer[0] = '\e' then
gotOne := false;
false
else
InputPtr := &InputBuffer[0];
skipBlanks();
not getCountry(pCountry)
fi
do
od;
gotOne
else
getCountry(pCountry)
fi
corp;
/*
* getChoice - see below.
*/
proc getChoice(*uint pWhat; *char choices)bool:
*char p, q;
uint result;
p := InputPtr;
skipWord();
q := InputPtr;
skipBlanks();
q* := '\e';
result := lookupCommand(choices, p);
if result = 0 then
err("unknown 'what'");
false
elif result = 1 then
err("ambiguous 'what'");
false
else
pWhat* := result - 2;
true
fi
corp;
/*
* reqChoice - get and check a word from a given set of choices. Just complain
* if it's from the command line, else prompt for a correct one. Return
* 'true' if we get a correct choice and set the 'what' parameter to the
* index of the choice in choices (0 origin).
*/
proc reqChoice(*uint pWhat; *char choices, prompt)bool:
bool quit, gotOne;
if InputPtr* = '\e' then
gotOne := true;
while
write(PromptOut; prompt);
if not readLine(&InputBuffer[0], INPUT_LENGTH) or
InputBuffer[0] = '\e' then
gotOne := false;
false
else
InputPtr := &InputBuffer[0];
skipBlanks();
not getChoice(pWhat, choices)
fi
do
od;
gotOne
else
getChoice(pWhat, choices)
fi
corp;
/*
* getShip - get a ship number from the input line.
*/
proc getShip(*uint pShip)bool:
int n;
uint n1;
if InputPtr* = '\e' then
false
else
if getNumber(&n) then
n1 := n;
if n >= 0 and n1 < World.w_shipNext then
pShip* := n1;
true
else
err("ship number out of range");
false
fi
else
false
fi
fi
corp;
/*
* reqShip - get (promting if needed) a ship number.
*/
proc reqShip(*uint pShip; *char prompt)bool:
bool gotOne;
if InputPtr* = '\e' then
gotOne := true;
while
write(PromptOut; prompt);
if not readLine(&InputBuffer[0], INPUT_LENGTH) or
InputBuffer[0] = '\e' then
gotOne := false;
false
else
InputPtr := &InputBuffer[0];
skipBlanks();
not getShip(pShip)
fi
do
od;
gotOne
else
getShip(pShip)
fi
corp;
/*
* getSectorOrShip - get a sector or ship spec.
*/
proc getSectorOrShip(*int pA, pB; *uint pS; *bool pIsShip)bool:
*char p;
p := InputPtr;
if p* = '-' then
/* has to be a sector spec */
pIsShip* := false;
getSector(pA, pB)
else
while p* >= '0' and p* <= '9' do
p := p + sizeof(char);
od;
if p* = ',' then
pIsShip* := false;
getSector(pA, pB)
else
pIsShip* := true;
getShip(pS)
fi
fi
corp;
/*
* reqSectorOrShip - get (prompting if needed) a single sector or ship spec.
*/
proc reqSectorOrShip(*int pA, pB; *uint pS; *bool pIsShip; *char prompt)bool:
bool gotOne;
if InputPtr* = '\e' then
gotOne := true;
while
write(PromptOut; prompt);
if not readLine(&InputBuffer[0], INPUT_LENGTH) or
InputBuffer[0] = '\e' then
gotOne := false;
false
else
InputPtr := &InputBuffer[0];
skipBlanks();
not getSectorOrShip(pA, pB, pS, pIsShip)
fi
do
od;
gotOne
else
getSectorOrShip(pA, pB, pS, pIsShip)
fi
corp;
/*
* getShipOrFleet - get a ship number or fleet letter.
*/
proc getShipOrFleet(*uint pShipNumber; *char pFleet)bool:
if InputPtr* >= '0' and InputPtr* <= '9' then
pFleet* := ' ';
if getShip(pShipNumber) then
if InputPtr* = ' ' or InputPtr* = '\t' or InputPtr* = '\e' then
true
else
err("extraneous characters after ship number");
false
fi
else
false
fi
elif InputPtr* >= 'a' and InputPtr* <= 'z' or
InputPtr* >= 'A' and InputPtr* <= 'Z' or InputPtr* = '*' then
pFleet* := InputPtr*;
InputPtr := InputPtr + sizeof(char);
true
else
err("invalid fleet character");
InputPtr* := '\e';
false
fi
corp;
/*
* reqShipOrFleet - request a ship number or fleet letter. Return a fleet
* letter of ' ' if a ship number is given.
*/
proc reqShipOrFleet(*uint pShipNumber; *char pFleet, prompt)bool:
bool gotOne;
if InputPtr* = '\e' then
gotOne := true;
while
write(Chout; prompt);
if not readLine(&InputBuffer[0], INPUT_LENGTH) or
InputBuffer[0] = '\e' then
gotOne := false;
false
else
InputPtr := &InputBuffer[0];
skipBlanks();
not getShipOrFleet(pShipNumber, pFleet)
fi
do
od;
gotOne
else
getShipOrFleet(pShipNumber, pFleet)
fi
corp;